#include <stdio.h>
#include <stdlib.h>
#include <Judy.h>

#include "datatypes.h"
#include "globals.h"

void free_role(Role* r) {
	int i;
	switch (r->type) {
	case ATOMIC_ROLE:
		// role names are reused, they are not freed!
		free(r->description.atomic);
		free(r);
		break;
	case ROLE_COMPOSITION:
		for (i = 0; i < r->description.role_composition->size; ++i)
			free_role(r->description.role_composition->roles[i]);
		free(r->description.role_composition);
		free(r);
		break;
	default:
		fprintf(stderr,"unknown role type, aborting\n");
		exit(-1);
	}
}

void free_concept(Concept* c) {
	int i;
	switch (c->type) {
		case ATOMIC_CONCEPT:
			// the name of the atomic concept is reused, do not free it!
			free(c->description.atomic);
			free(c);
			break;
		case EXISTENTIAL_RESTRICTION:
			// there can be only atomic roles in exist restrictions
			// atomic roles are reused, shouldn't be freed!
			free_role(c->description.exists->role);
			free_concept(c->description.exists->filler);
			free(c->description.exists);
			free(c);
			break;
		case CONJUNCTION:
			for (i = 0; i < c->description.conj->count; ++i) {
				free_concept(c->description.conj->conjuncts[i]);
			}
			free(c->description.conj);
			free(c);
			break;
		default:
			fprintf(stderr,"unknown concept type, aborting\n");
			printf("type:%d\n",c->type);
			exit(-1);
	}

}



void free_eqclass_axiom(Axiom* ax) {
	free_concept(ax->body.eqclass_ax->lhs);
	free_concept(ax->body.eqclass_ax->rhs);
	free(ax->body.eqclass_ax);
	free(ax);
}

void free_subclass_axiom(Axiom* ax) {
	free_concept(ax->body.subclass_ax->rhs);
	free_concept(ax->body.subclass_ax->lhs);
	free(ax->body.subclass_ax);
	free(ax);
}

void free_subrole_axiom(Axiom* ax) {
	free_role(ax->body.subrole_ax->lhs);
	free_role(ax->body.subrole_ax->rhs);
	free(ax->body.subrole_ax);
	free(ax);
}


void free_axiom(Axiom* ax) {
	switch (ax->type) {
		case SUBCLASS_AX:
			free_subclass_axiom(ax);
			break;
		case EQCLASS_AX:
			free_eqclass_axiom(ax);
			break;
		case SUBROLE_AX:
			free_subrole_axiom(ax);
			break;
		default:
			fprintf(stderr, "unknown axiom type, aborting\n");
			exit(-1);
	}
}

void free_original_kb() {
	int i;
	Word_t judy_return;

	for (i = 0; i < tbox.axiom_count; ++i)
		free_axiom(tbox.axioms[i]);

	JSLFA(judy_return, atomic_concepts);
	JSLFA(judy_return, atomic_roles);
}
